package plp.functional2.declaration;

import java.util.List;

import plp.expressions2.expression.Id;
import plp.expressions2.memory.AmbienteCompilacao;
import plp.expressions2.memory.ContextoCompilacao;
import plp.expressions2.memory.VariavelJaDeclaradaException;
import plp.expressions2.memory.VariavelNaoDeclaradaException;
import plp.functional1.util.TipoPolimorfico;
import plp.functional2.primitive.Primitiva;

public class DefProcesso{

	private List<Id> listId;
	private Primitiva primitiva;

	public DefProcesso(List<Id> argsId, Primitiva primitiva) {
		this.listId = argsId;
		this.primitiva = primitiva;
	}

	public List<Id> getListaId() {
		return listId;
	}

	public Primitiva getPrimitiva() {
		return primitiva;
	}


	/**
	 * Realiza a verificacao de tipos desta declara��o.
	 * 
	 * @param amb
	 *            o ambiente de compila��o.
	 * @return <code>true</code> se os tipos da expressao sao valIdos;
	 *         <code>false</code> caso contrario.
	 * @exception IdiavelNaoDeclaradaException
	 *                se existir um Identificador nao declarado no ambiente.
	 * @exception IdiavelNaoDeclaradaException
	 *                se existir um Identificador declarado mais de uma vez no
	 *                mesmo bloco do ambiente.
	 */
	public boolean checaTipo(AmbienteCompilacao ambiente)
			throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException {
		ContextoCompilacao ambProcesso = (ContextoCompilacao)ambiente;
		ambProcesso.incrementa();

		// Usa uma inst�ncia de TipoQualquer para cada par�metro formal.
		// Essa inst�ncia ser� inferIda durante o getTipo de exp.
		for (Id Id : listId) {
			ambProcesso.map(Id, new TipoPolimorfico());
		}

		// Chama o checa tipo da express�o para veririficar se o corpo da
		// fun��o est� correto. Isto ir� inferir o tipo dos par�metros.
		boolean result = primitiva.checaTipo(ambProcesso);

		ambProcesso.restaura();

		return result;
	}
}